#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
对外 api token 和 推送配置管理
"""
import uuid
import datetime
import arrow

from flask import jsonify, g
from app.libs.redprint import RedPrint
from app.log.logs import CApiLog, UApiLog
from app.db.models.api_token import OutPutConfig, ApiToken
from app.errors import APIException, PermissionDenied, ParameterError
from app.validators.api_token import ApiTokenForm, SendMessageConfigForm
from app.libs.api_send_message import send_message
from app.libs.api_utils import check_api_module
from app.libs.enums import TASK_TYPE_CONFIG


api = RedPrint('api')


@api.route('/config_detail', methods=['GET'])
def config_detail():
    """查询推送配置详情"""
    obj = OutPutConfig.objects.filter(uid=g.user.id).first()
    if not obj:
        return jsonify({})
    data = obj.to_mongo().to_dict()
    data.pop("_cls", "")
    data["id"] = data.pop("_id", "")
    return jsonify(data)


@api.route('/token_detail', methods=['GET'])
def token_detail():
    """查询api token详情"""
    obj = ApiToken.objects.filter(uid=g.user.id).first()
    if not obj:
        return jsonify({})
    data = obj.to_mongo().to_dict()
    data.pop("_cls", "")
    data["id"] = data.pop("_id", "")
    return jsonify(data)


@api.route('/token_update', methods=['POST'])
def token_update():
    """创建、更新token"""
    api_exp = check_api_module(g.user.id)
    if not api_exp:
        raise PermissionDenied(msg="API 模块过期")
    form = ApiTokenForm().validate_for_api()
    expired_time = arrow.get(form.expired_time.data).datetime
    if expired_time.timestamp() > api_exp:
        raise APIException(msg="token 过期时间不能超过API模块到期时间")
    is_active = form.is_active.data
    is_new_create = form.is_new_create.data
    desc = form.desc.data
    obj = ApiToken.objects.filter(uid=g.user.id).first()
    if (not obj) or is_new_create:
        token = uuid.uuid4().hex
    else:
        token = obj.token
    log_msg = "创建API token" if not obj else "更新API token"
    create = False
    if not obj:
        create = True
    log_class = CApiLog if not obj else UApiLog
    obj = obj if obj else ApiToken()
    obj.token = token
    obj.expired_time = expired_time
    obj.is_active = is_active
    obj.desc = desc
    obj.uid = g.user.id
    if create:
        obj.created_at = datetime.datetime.utcnow()
    obj.updated_at = datetime.datetime.utcnow()
    obj.save()
    log_class().info(log_msg, f"token值: {token[:8]}*********{token[-8:]}, 过期时间: {expired_time}, 备注为:{desc}")
    return jsonify({'id': str(obj.id), 'token': token, 'expired_time': expired_time, "is_active": obj.is_active})


@api.route('/config_update', methods=['POST'])
def config_update():
    """更新推送配置"""
    if not check_api_module(g.user.id):
        raise PermissionDenied(msg="API 模块过期")
    form = SendMessageConfigForm().validate_for_api()
    obj = OutPutConfig.objects.filter(uid=g.user.id).first()
    create = False
    if not obj:
        create = True
    log_msg = "创建推送配置" if not obj else "更新推送配置"
    obj = obj if obj else OutPutConfig()
    obj.is_active = form.is_active.data
    obj.url = form.url.data
    obj.auth_type = form.auth_type.data
    obj.add_to = form.add_to.data
    obj.auth_key = form.auth_key.data
    obj.auth_value = form.auth_value.data
    obj.method = form.method.data
    obj.desc = form.desc.data
    obj.uid = g.user.id
    obj.push_task_types = list(set(form.task_types.data))
    if create:
        obj.created_at = datetime.datetime.utcnow()
    obj.updated_at = datetime.datetime.utcnow()
    obj.save()
    detail = (f"推送配置, URL: {obj.url}| 是否启用推送: {obj.is_active}| 备注: {obj.desc} | 访问方法: {obj.method} | \
                认证KEY/用户名: {obj.auth_key} | 认证值/密码: ****** | \
                推送任务类型 {[TASK_TYPE_CONFIG[t]['cn'] for t in obj.push_task_types]}")
    UApiLog().info(log_msg, detail)
    data = obj.to_mongo()
    data.pop("_cls", "")
    data["id"] = data.pop("_id", "")
    return jsonify(data)


@api.route('/config_test', methods=['POST'])
def config_test():
    """测试推送配置"""
    if not check_api_module(g.user.id):
        raise PermissionDenied(msg="API 模块过期")
    obj = OutPutConfig.objects.filter(uid=g.user.id).first()
    if (not obj) or (not obj.url):
        raise APIException(msg="没有配置推送地址")
    flag, message = send_message("这是一条测试消息", url_obj=obj)
    if flag:
        return jsonify({"status": "success", "errcode": 0, "message": message})
    return jsonify(
        data={"status": "fail", "errcode": -1, "message": f"推送失败, 接口响应结果是: {message}"},
        status=400
    )
